package com.hooya.fa.eu.biz.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.hooya.fa.eu.api.bo.report.ProfitCheckBO;
import com.hooya.fa.eu.biz.dao.entity.ProfitCheck;
import com.hooya.fa.eu.biz.dao.entity.ProfitCheckRecord;
import com.hooya.fa.eu.biz.dao.repository.ProfitCheckRecordRepository;
import com.hooya.fa.eu.biz.dao.repository.ProfitCheckRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 1
 * @Author : Zongz
 * @Copyright Copyright (c) 豪雅集团
 * @Create 2024/1/10
 * @Version 1.0.0
 */
@Slf4j
@DS("fa_eu")
public class ProfitCheckListener implements ReadListener<ProfitCheckBO> {

    private final IdentifierGenerator identifierGenerator;

    private final ProfitCheckRepository profitCheckRepository;

    private final ProfitCheckRecordRepository profitCheckRecordRepository;

    private String belongs;

    private String date;

    private static final int BATCH_COUNT = 1000;

    private List<ProfitCheckBO> cacheData = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public ProfitCheckListener(String belongs, String date, ProfitCheckRepository profitCheckRepository,
                               ProfitCheckRecordRepository profitCheckRecordRepository,
                               IdentifierGenerator identifierGenerator) {
        this.belongs = belongs;
        this.date = date;
        this.identifierGenerator = identifierGenerator;
        this.profitCheckRepository = profitCheckRepository;
        this.profitCheckRecordRepository = profitCheckRecordRepository;
    }

    @Override
    public void invoke(ProfitCheckBO data, AnalysisContext context) {
        cacheData.add(data);
        if (cacheData.size() >= BATCH_COUNT) {
            saveProfitCheck();
            cacheData = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveProfitCheck();
        log.info("所有数据解析完成！");
    }


    public void saveProfitCheck() {
        List<ProfitCheck> profitCheckList = new LinkedList<>();
        List<ProfitCheckRecord> profitCheckRecordList = new LinkedList<>();
        Map<String, List<ProfitCheckBO>> profitCheckMap = cacheData.stream()
                .collect(Collectors.groupingBy(p -> p.getSku() +
                        (StringUtils.isNotBlank(p.getInvoiceNumber()) ? p.getInvoiceNumber() : "")));
        //csv空行问题
        profitCheckMap.remove("null");
        profitCheckMap.forEach((k, l) -> {
            int id = identifierGenerator.nextId(new ProfitCheck()).intValue();
            int remainingNum = l.stream().mapToInt(ProfitCheckBO::getEndOfTheMonthStock).sum();
            ProfitCheck profitCheck = ProfitCheck.builder().id(id).sku(l.get(0).getSku())
                    .invoiceNo(l.get(0).getInvoiceNumber()).belongs(belongs).date(date)
                    .remainingNum(remainingNum).build();
            profitCheckList.add(profitCheck);
            for (ProfitCheckBO bo : l) {
                ProfitCheckRecord profitCheckRecord = ProfitCheckRecord.builder().profitCheckId(id)
                        .invoiceDate(bo.getInvoiceDate()).inboundDate(bo.getInboundDate())
                        .beginStockNum(bo.getBeginOfTheMonthStock()).endStockNum(bo.getEndOfTheMonthStock())
                        .inbound(bo.getInbound()).sales(bo.getSales()).lost(bo.getLost()).restock(bo.getRestock())
                        .inPriceEur(bo.getInPriceEur()).inPriceUsd(bo.getInPriceUsd())
                        .currencyRate(bo.getCurrencyRate()).pln(bo.getPln()).type(bo.getType())
                        .transfer(bo.getTransfer()).flag(bo.getFlag()).build();
                profitCheckRecordList.add(profitCheckRecord);
            }
        });
//        transactionTemplate.execute(status -> {
        profitCheckRepository.batchSave(profitCheckList);
        profitCheckRecordRepository.batchSave(profitCheckRecordList);
//            return true;
//        });
    }
}
